package com.peaksport.framework.base.service;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TemporalType;
import javax.transaction.Transactional;

import org.apache.servicecomb.provider.springmvc.reference.async.CseAsyncRestTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.client.RestTemplate;

import com.peaksport.framework.base.dao.IBaseDAO;
import com.peaksport.framework.base.entity.IEntityObject;
import com.peaksport.framework.extend.redis.PKRedisTemplate;
import com.peaksport.framework.metadata.view.EntityViewInfo;
import com.peaksport.framework.util.PKContextUtils;
import com.peaksport.framework.util.PKDevUtils;
import com.peaksport.framework.util.PKPublicUtils;
import com.peaksport.framework.vo.SessionInfo;

public abstract class CoreBaseService {

	//未指定具体的dao时，使用通用的Dao
	@Autowired
	private IBaseDAO<?> baseDAO;
	
	@Autowired
	public PKRedisTemplate pkRedisTemplate;
	
	@Autowired
	public RestTemplate restTemplate;
	
	@Autowired
	public CseAsyncRestTemplate asynRestTemplate;
	
	/**
	 * 判断空值
	 * 
	 * @param obj
	 * @param formatStr
	 * @param args
	 */
	public void verifyBizNull(Object obj, String formatStr,Object... args) {
		PKPublicUtils.verifyBizNull(obj, formatStr, args);
	}
	
	/**
	 * 判断空值(接口调用或传参异常,开发运行时用)
	 * @param obj
	 * @param formatStr
	 * @param args
	 */
	public void verifyDevNull(Object obj, String formatStr,Object... args) {
		PKDevUtils.verifyDevNull(obj, formatStr, args);
	} 
	

	@SuppressWarnings("unchecked")
	public <T> T queryOneValueForNative(String sql,Class<T> resultClass) {
		IBaseDAO<?> dao = _getDAO();
		return (T)dao.queryOneValueForNative(sql);
	}
	
	public <T> T queryOneRecordForNative(String sql, Class<T> resultClass) {
		return queryOneRecordForNative(sql,resultClass,true);
	}
	
	@SuppressWarnings("unchecked")
	public <T> T queryOneRecordForNative(String sql, Class<T> resultClass, boolean isMapTransfer) {
		IBaseDAO<?> dao = _getDAO();
		return (T)dao.queryOneRecordForNative(sql, resultClass, isMapTransfer);
	}
	
	
	public List<?> queryRecordForNative(String sql, Class<?> resultClass) {
		IBaseDAO<?> dao = _getDAO();
		return dao.queryRecordForNative(sql, resultClass);
	}
	
	
	public List<?> queryRecordForNative(String sql, Class<?> resultClass, boolean isMapTransfer) {
		IBaseDAO<?> dao = _getDAO();
		return dao.queryRecordForNative(sql, resultClass,isMapTransfer);
	}
	
	public boolean isExistsForNative(String sql) {
		IBaseDAO<?> dao = _getDAO();
		return dao.isExistsForNative(sql);
	}
	
	public boolean delete(String pk) {
		IBaseDAO<?> dao = _getDAO();
		return dao.delete(pk);
	}
	
	public int executeSqlForNative(String sql,String[] paramNames,Object[] paramValues,HashMap<String, TemporalType> dateTemporalType) {
		IBaseDAO<?> dao = _getDAO();
		return dao.executeSqlForNative(sql, paramNames, paramValues, dateTemporalType);
	}
	public int executeSqlForNative(String sql) {
		return executeSqlForNative(sql,null,null,null);
	}

	public int[] batchExecuteSqlForNative(String...sqls) {
		IBaseDAO<?> dao = _getDAO();
		return dao.batchExecuteSqlForNative(sqls);
	}

	public Date getCurrentTime() {
		IBaseDAO<?> dao = _getDAO();
		return dao.getCurrentTime();
	}
	
	public abstract IBaseDAO<?> getDAO();
	

	private IBaseDAO<?> _getDAO() {
		IBaseDAO<?> dao = getDAO();
		if (dao == null) dao = baseDAO;
		return dao;
	}
	

	@Transactional
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public IEntityObject save(IEntityObject entity) {
		IBaseDAO dao = _getDAO();
		dao.save(entity);
		return entity;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public <T> T getValue(EntityViewInfo entityViewInfo,Class<T> entityClass) {
		IBaseDAO dao = _getDAO();
		T entity = (T) dao.getValue(entityViewInfo, entityClass);
		return entity;
	}
	
	
	
	/**
	 * 获取contextInfo 会话信息
	 * @return
	 */
	public SessionInfo getSessionInfo() {
		return PKContextUtils.getSessionInfo(pkRedisTemplate);
	}
	
	/**
	 * 存放contextInfo 会话信息
	 * @param contextInfo
	 */
	public void setSessionInfo(SessionInfo sessionInfo) {
		 verifyBizNull(sessionInfo, "会话信息对象不能为空.");
		 PKContextUtils.setSessionInfo(pkRedisTemplate, sessionInfo);
	}
	
	/**
	 * URL 反编码
	 * @param s
	 * @return
	 */
	public String urlDecode(String s) {
		return URLDecoder.decode(s);
	}
	
	/**
	 * URL 编码
	 * @param s
	 * @return
	 */
	public String urlEncode(String s) {
		return URLEncoder.encode(s);
	}
	
}
